{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "name": "W5_Homework",
      "provenance": [],
      "collapsed_sections": [],
      "toc_visible": true,
      "include_colab_link": true
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    },
    "accelerator": "GPU",
    "widgets": {
      "application/vnd.jupyter.widget-state+json": {
        "9d491335bbca4d5c8a19cee359753550": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "HBoxModel",
          "state": {
            "_view_name": "HBoxView",
            "_dom_classes": [],
            "_model_name": "HBoxModel",
            "_view_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_view_count": null,
            "_view_module_version": "1.5.0",
            "box_style": "",
            "layout": "IPY_MODEL_db3e065b5beb406280291a97df02ae19",
            "_model_module": "@jupyter-widgets/controls",
            "children": [
              "IPY_MODEL_8b28a0eef01645f0a656ad12213942bd",
              "IPY_MODEL_fba9a8c97e604df7a7f9db8cbac56f00"
            ]
          }
        },
        "db3e065b5beb406280291a97df02ae19": {
          "model_module": "@jupyter-widgets/base",
          "model_name": "LayoutModel",
          "state": {
            "_view_name": "LayoutView",
            "grid_template_rows": null,
            "right": null,
            "justify_content": null,
            "_view_module": "@jupyter-widgets/base",
            "overflow": null,
            "_model_module_version": "1.2.0",
            "_view_count": null,
            "flex_flow": null,
            "width": null,
            "min_width": null,
            "border": null,
            "align_items": null,
            "bottom": null,
            "_model_module": "@jupyter-widgets/base",
            "top": null,
            "grid_column": null,
            "overflow_y": null,
            "overflow_x": null,
            "grid_auto_flow": null,
            "grid_area": null,
            "grid_template_columns": null,
            "flex": null,
            "_model_name": "LayoutModel",
            "justify_items": null,
            "grid_row": null,
            "max_height": null,
            "align_content": null,
            "visibility": null,
            "align_self": null,
            "height": null,
            "min_height": null,
            "padding": null,
            "grid_auto_rows": null,
            "grid_gap": null,
            "max_width": null,
            "order": null,
            "_view_module_version": "1.2.0",
            "grid_template_areas": null,
            "object_position": null,
            "object_fit": null,
            "grid_auto_columns": null,
            "margin": null,
            "display": null,
            "left": null
          }
        },
        "8b28a0eef01645f0a656ad12213942bd": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "FloatProgressModel",
          "state": {
            "_view_name": "ProgressView",
            "style": "IPY_MODEL_2f7ac9f494674fbd89837fed0617d291",
            "_dom_classes": [],
            "description": "",
            "_model_name": "FloatProgressModel",
            "bar_style": "success",
            "max": 1,
            "_view_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "value": 1,
            "_view_count": null,
            "_view_module_version": "1.5.0",
            "orientation": "horizontal",
            "min": 0,
            "description_tooltip": null,
            "_model_module": "@jupyter-widgets/controls",
            "layout": "IPY_MODEL_75b1108264d746138c493220ad8477aa"
          }
        },
        "fba9a8c97e604df7a7f9db8cbac56f00": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "HTMLModel",
          "state": {
            "_view_name": "HTMLView",
            "style": "IPY_MODEL_5bb338a1f35a46139174bd02e9b4b1f3",
            "_dom_classes": [],
            "description": "",
            "_model_name": "HTMLModel",
            "placeholder": "​",
            "_view_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "value": " 9920512/? [00:06&lt;00:00, 1467538.97it/s]",
            "_view_count": null,
            "_view_module_version": "1.5.0",
            "description_tooltip": null,
            "_model_module": "@jupyter-widgets/controls",
            "layout": "IPY_MODEL_e922415f57914427a8777c051081c094"
          }
        },
        "2f7ac9f494674fbd89837fed0617d291": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "ProgressStyleModel",
          "state": {
            "_view_name": "StyleView",
            "_model_name": "ProgressStyleModel",
            "description_width": "initial",
            "_view_module": "@jupyter-widgets/base",
            "_model_module_version": "1.5.0",
            "_view_count": null,
            "_view_module_version": "1.2.0",
            "bar_color": null,
            "_model_module": "@jupyter-widgets/controls"
          }
        },
        "75b1108264d746138c493220ad8477aa": {
          "model_module": "@jupyter-widgets/base",
          "model_name": "LayoutModel",
          "state": {
            "_view_name": "LayoutView",
            "grid_template_rows": null,
            "right": null,
            "justify_content": null,
            "_view_module": "@jupyter-widgets/base",
            "overflow": null,
            "_model_module_version": "1.2.0",
            "_view_count": null,
            "flex_flow": null,
            "width": null,
            "min_width": null,
            "border": null,
            "align_items": null,
            "bottom": null,
            "_model_module": "@jupyter-widgets/base",
            "top": null,
            "grid_column": null,
            "overflow_y": null,
            "overflow_x": null,
            "grid_auto_flow": null,
            "grid_area": null,
            "grid_template_columns": null,
            "flex": null,
            "_model_name": "LayoutModel",
            "justify_items": null,
            "grid_row": null,
            "max_height": null,
            "align_content": null,
            "visibility": null,
            "align_self": null,
            "height": null,
            "min_height": null,
            "padding": null,
            "grid_auto_rows": null,
            "grid_gap": null,
            "max_width": null,
            "order": null,
            "_view_module_version": "1.2.0",
            "grid_template_areas": null,
            "object_position": null,
            "object_fit": null,
            "grid_auto_columns": null,
            "margin": null,
            "display": null,
            "left": null
          }
        },
        "5bb338a1f35a46139174bd02e9b4b1f3": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "DescriptionStyleModel",
          "state": {
            "_view_name": "StyleView",
            "_model_name": "DescriptionStyleModel",
            "description_width": "",
            "_view_module": "@jupyter-widgets/base",
            "_model_module_version": "1.5.0",
            "_view_count": null,
            "_view_module_version": "1.2.0",
            "_model_module": "@jupyter-widgets/controls"
          }
        },
        "e922415f57914427a8777c051081c094": {
          "model_module": "@jupyter-widgets/base",
          "model_name": "LayoutModel",
          "state": {
            "_view_name": "LayoutView",
            "grid_template_rows": null,
            "right": null,
            "justify_content": null,
            "_view_module": "@jupyter-widgets/base",
            "overflow": null,
            "_model_module_version": "1.2.0",
            "_view_count": null,
            "flex_flow": null,
            "width": null,
            "min_width": null,
            "border": null,
            "align_items": null,
            "bottom": null,
            "_model_module": "@jupyter-widgets/base",
            "top": null,
            "grid_column": null,
            "overflow_y": null,
            "overflow_x": null,
            "grid_auto_flow": null,
            "grid_area": null,
            "grid_template_columns": null,
            "flex": null,
            "_model_name": "LayoutModel",
            "justify_items": null,
            "grid_row": null,
            "max_height": null,
            "align_content": null,
            "visibility": null,
            "align_self": null,
            "height": null,
            "min_height": null,
            "padding": null,
            "grid_auto_rows": null,
            "grid_gap": null,
            "max_width": null,
            "order": null,
            "_view_module_version": "1.2.0",
            "grid_template_areas": null,
            "object_position": null,
            "object_fit": null,
            "grid_auto_columns": null,
            "margin": null,
            "display": null,
            "left": null
          }
        },
        "b0fb7494f9a6411c883e75ce3abed7a9": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "HBoxModel",
          "state": {
            "_view_name": "HBoxView",
            "_dom_classes": [],
            "_model_name": "HBoxModel",
            "_view_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_view_count": null,
            "_view_module_version": "1.5.0",
            "box_style": "",
            "layout": "IPY_MODEL_7e945698d3484fef95f009521dd82987",
            "_model_module": "@jupyter-widgets/controls",
            "children": [
              "IPY_MODEL_a7983575d08145839f029e607b83f154",
              "IPY_MODEL_3775f41ba88f43a6ad52a4bee451c3b8"
            ]
          }
        },
        "7e945698d3484fef95f009521dd82987": {
          "model_module": "@jupyter-widgets/base",
          "model_name": "LayoutModel",
          "state": {
            "_view_name": "LayoutView",
            "grid_template_rows": null,
            "right": null,
            "justify_content": null,
            "_view_module": "@jupyter-widgets/base",
            "overflow": null,
            "_model_module_version": "1.2.0",
            "_view_count": null,
            "flex_flow": null,
            "width": null,
            "min_width": null,
            "border": null,
            "align_items": null,
            "bottom": null,
            "_model_module": "@jupyter-widgets/base",
            "top": null,
            "grid_column": null,
            "overflow_y": null,
            "overflow_x": null,
            "grid_auto_flow": null,
            "grid_area": null,
            "grid_template_columns": null,
            "flex": null,
            "_model_name": "LayoutModel",
            "justify_items": null,
            "grid_row": null,
            "max_height": null,
            "align_content": null,
            "visibility": null,
            "align_self": null,
            "height": null,
            "min_height": null,
            "padding": null,
            "grid_auto_rows": null,
            "grid_gap": null,
            "max_width": null,
            "order": null,
            "_view_module_version": "1.2.0",
            "grid_template_areas": null,
            "object_position": null,
            "object_fit": null,
            "grid_auto_columns": null,
            "margin": null,
            "display": null,
            "left": null
          }
        },
        "a7983575d08145839f029e607b83f154": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "FloatProgressModel",
          "state": {
            "_view_name": "ProgressView",
            "style": "IPY_MODEL_f50db837dec542e0acdf4b1a66b493d4",
            "_dom_classes": [],
            "description": "",
            "_model_name": "FloatProgressModel",
            "bar_style": "success",
            "max": 1,
            "_view_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "value": 1,
            "_view_count": null,
            "_view_module_version": "1.5.0",
            "orientation": "horizontal",
            "min": 0,
            "description_tooltip": null,
            "_model_module": "@jupyter-widgets/controls",
            "layout": "IPY_MODEL_290985f35f2a47e5a209981ca3679bc5"
          }
        },
        "3775f41ba88f43a6ad52a4bee451c3b8": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "HTMLModel",
          "state": {
            "_view_name": "HTMLView",
            "style": "IPY_MODEL_3badfe47858d43f68a2d497a4ac009fa",
            "_dom_classes": [],
            "description": "",
            "_model_name": "HTMLModel",
            "placeholder": "​",
            "_view_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "value": " 32768/? [00:03&lt;00:00, 9152.12it/s]",
            "_view_count": null,
            "_view_module_version": "1.5.0",
            "description_tooltip": null,
            "_model_module": "@jupyter-widgets/controls",
            "layout": "IPY_MODEL_88eac33ca8ef43eda70f90000c11124a"
          }
        },
        "f50db837dec542e0acdf4b1a66b493d4": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "ProgressStyleModel",
          "state": {
            "_view_name": "StyleView",
            "_model_name": "ProgressStyleModel",
            "description_width": "initial",
            "_view_module": "@jupyter-widgets/base",
            "_model_module_version": "1.5.0",
            "_view_count": null,
            "_view_module_version": "1.2.0",
            "bar_color": null,
            "_model_module": "@jupyter-widgets/controls"
          }
        },
        "290985f35f2a47e5a209981ca3679bc5": {
          "model_module": "@jupyter-widgets/base",
          "model_name": "LayoutModel",
          "state": {
            "_view_name": "LayoutView",
            "grid_template_rows": null,
            "right": null,
            "justify_content": null,
            "_view_module": "@jupyter-widgets/base",
            "overflow": null,
            "_model_module_version": "1.2.0",
            "_view_count": null,
            "flex_flow": null,
            "width": null,
            "min_width": null,
            "border": null,
            "align_items": null,
            "bottom": null,
            "_model_module": "@jupyter-widgets/base",
            "top": null,
            "grid_column": null,
            "overflow_y": null,
            "overflow_x": null,
            "grid_auto_flow": null,
            "grid_area": null,
            "grid_template_columns": null,
            "flex": null,
            "_model_name": "LayoutModel",
            "justify_items": null,
            "grid_row": null,
            "max_height": null,
            "align_content": null,
            "visibility": null,
            "align_self": null,
            "height": null,
            "min_height": null,
            "padding": null,
            "grid_auto_rows": null,
            "grid_gap": null,
            "max_width": null,
            "order": null,
            "_view_module_version": "1.2.0",
            "grid_template_areas": null,
            "object_position": null,
            "object_fit": null,
            "grid_auto_columns": null,
            "margin": null,
            "display": null,
            "left": null
          }
        },
        "3badfe47858d43f68a2d497a4ac009fa": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "DescriptionStyleModel",
          "state": {
            "_view_name": "StyleView",
            "_model_name": "DescriptionStyleModel",
            "description_width": "",
            "_view_module": "@jupyter-widgets/base",
            "_model_module_version": "1.5.0",
            "_view_count": null,
            "_view_module_version": "1.2.0",
            "_model_module": "@jupyter-widgets/controls"
          }
        },
        "88eac33ca8ef43eda70f90000c11124a": {
          "model_module": "@jupyter-widgets/base",
          "model_name": "LayoutModel",
          "state": {
            "_view_name": "LayoutView",
            "grid_template_rows": null,
            "right": null,
            "justify_content": null,
            "_view_module": "@jupyter-widgets/base",
            "overflow": null,
            "_model_module_version": "1.2.0",
            "_view_count": null,
            "flex_flow": null,
            "width": null,
            "min_width": null,
            "border": null,
            "align_items": null,
            "bottom": null,
            "_model_module": "@jupyter-widgets/base",
            "top": null,
            "grid_column": null,
            "overflow_y": null,
            "overflow_x": null,
            "grid_auto_flow": null,
            "grid_area": null,
            "grid_template_columns": null,
            "flex": null,
            "_model_name": "LayoutModel",
            "justify_items": null,
            "grid_row": null,
            "max_height": null,
            "align_content": null,
            "visibility": null,
            "align_self": null,
            "height": null,
            "min_height": null,
            "padding": null,
            "grid_auto_rows": null,
            "grid_gap": null,
            "max_width": null,
            "order": null,
            "_view_module_version": "1.2.0",
            "grid_template_areas": null,
            "object_position": null,
            "object_fit": null,
            "grid_auto_columns": null,
            "margin": null,
            "display": null,
            "left": null
          }
        },
        "e03e9765e6b5469299552f4c07762285": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "HBoxModel",
          "state": {
            "_view_name": "HBoxView",
            "_dom_classes": [],
            "_model_name": "HBoxModel",
            "_view_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_view_count": null,
            "_view_module_version": "1.5.0",
            "box_style": "",
            "layout": "IPY_MODEL_f0591e73e0d94af78d4f3085764e8746",
            "_model_module": "@jupyter-widgets/controls",
            "children": [
              "IPY_MODEL_2124c1492c744ed2ba519bd274f0c90f",
              "IPY_MODEL_f9c8ea2bda7d430f88693c0eda8a1d4a"
            ]
          }
        },
        "f0591e73e0d94af78d4f3085764e8746": {
          "model_module": "@jupyter-widgets/base",
          "model_name": "LayoutModel",
          "state": {
            "_view_name": "LayoutView",
            "grid_template_rows": null,
            "right": null,
            "justify_content": null,
            "_view_module": "@jupyter-widgets/base",
            "overflow": null,
            "_model_module_version": "1.2.0",
            "_view_count": null,
            "flex_flow": null,
            "width": null,
            "min_width": null,
            "border": null,
            "align_items": null,
            "bottom": null,
            "_model_module": "@jupyter-widgets/base",
            "top": null,
            "grid_column": null,
            "overflow_y": null,
            "overflow_x": null,
            "grid_auto_flow": null,
            "grid_area": null,
            "grid_template_columns": null,
            "flex": null,
            "_model_name": "LayoutModel",
            "justify_items": null,
            "grid_row": null,
            "max_height": null,
            "align_content": null,
            "visibility": null,
            "align_self": null,
            "height": null,
            "min_height": null,
            "padding": null,
            "grid_auto_rows": null,
            "grid_gap": null,
            "max_width": null,
            "order": null,
            "_view_module_version": "1.2.0",
            "grid_template_areas": null,
            "object_position": null,
            "object_fit": null,
            "grid_auto_columns": null,
            "margin": null,
            "display": null,
            "left": null
          }
        },
        "2124c1492c744ed2ba519bd274f0c90f": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "FloatProgressModel",
          "state": {
            "_view_name": "ProgressView",
            "style": "IPY_MODEL_3b4ad40f535049738154dbbcfa2966bf",
            "_dom_classes": [],
            "description": "",
            "_model_name": "FloatProgressModel",
            "bar_style": "success",
            "max": 1,
            "_view_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "value": 1,
            "_view_count": null,
            "_view_module_version": "1.5.0",
            "orientation": "horizontal",
            "min": 0,
            "description_tooltip": null,
            "_model_module": "@jupyter-widgets/controls",
            "layout": "IPY_MODEL_05429b65a91b49dab1ca4e3461d9de30"
          }
        },
        "f9c8ea2bda7d430f88693c0eda8a1d4a": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "HTMLModel",
          "state": {
            "_view_name": "HTMLView",
            "style": "IPY_MODEL_d3cf3f3f647b4280a101c41539db3586",
            "_dom_classes": [],
            "description": "",
            "_model_name": "HTMLModel",
            "placeholder": "​",
            "_view_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "value": " 1654784/? [00:02&lt;00:00, 643976.84it/s]",
            "_view_count": null,
            "_view_module_version": "1.5.0",
            "description_tooltip": null,
            "_model_module": "@jupyter-widgets/controls",
            "layout": "IPY_MODEL_5dd7edbcb0a64590a1252524b34ca67e"
          }
        },
        "3b4ad40f535049738154dbbcfa2966bf": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "ProgressStyleModel",
          "state": {
            "_view_name": "StyleView",
            "_model_name": "ProgressStyleModel",
            "description_width": "initial",
            "_view_module": "@jupyter-widgets/base",
            "_model_module_version": "1.5.0",
            "_view_count": null,
            "_view_module_version": "1.2.0",
            "bar_color": null,
            "_model_module": "@jupyter-widgets/controls"
          }
        },
        "05429b65a91b49dab1ca4e3461d9de30": {
          "model_module": "@jupyter-widgets/base",
          "model_name": "LayoutModel",
          "state": {
            "_view_name": "LayoutView",
            "grid_template_rows": null,
            "right": null,
            "justify_content": null,
            "_view_module": "@jupyter-widgets/base",
            "overflow": null,
            "_model_module_version": "1.2.0",
            "_view_count": null,
            "flex_flow": null,
            "width": null,
            "min_width": null,
            "border": null,
            "align_items": null,
            "bottom": null,
            "_model_module": "@jupyter-widgets/base",
            "top": null,
            "grid_column": null,
            "overflow_y": null,
            "overflow_x": null,
            "grid_auto_flow": null,
            "grid_area": null,
            "grid_template_columns": null,
            "flex": null,
            "_model_name": "LayoutModel",
            "justify_items": null,
            "grid_row": null,
            "max_height": null,
            "align_content": null,
            "visibility": null,
            "align_self": null,
            "height": null,
            "min_height": null,
            "padding": null,
            "grid_auto_rows": null,
            "grid_gap": null,
            "max_width": null,
            "order": null,
            "_view_module_version": "1.2.0",
            "grid_template_areas": null,
            "object_position": null,
            "object_fit": null,
            "grid_auto_columns": null,
            "margin": null,
            "display": null,
            "left": null
          }
        },
        "d3cf3f3f647b4280a101c41539db3586": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "DescriptionStyleModel",
          "state": {
            "_view_name": "StyleView",
            "_model_name": "DescriptionStyleModel",
            "description_width": "",
            "_view_module": "@jupyter-widgets/base",
            "_model_module_version": "1.5.0",
            "_view_count": null,
            "_view_module_version": "1.2.0",
            "_model_module": "@jupyter-widgets/controls"
          }
        },
        "5dd7edbcb0a64590a1252524b34ca67e": {
          "model_module": "@jupyter-widgets/base",
          "model_name": "LayoutModel",
          "state": {
            "_view_name": "LayoutView",
            "grid_template_rows": null,
            "right": null,
            "justify_content": null,
            "_view_module": "@jupyter-widgets/base",
            "overflow": null,
            "_model_module_version": "1.2.0",
            "_view_count": null,
            "flex_flow": null,
            "width": null,
            "min_width": null,
            "border": null,
            "align_items": null,
            "bottom": null,
            "_model_module": "@jupyter-widgets/base",
            "top": null,
            "grid_column": null,
            "overflow_y": null,
            "overflow_x": null,
            "grid_auto_flow": null,
            "grid_area": null,
            "grid_template_columns": null,
            "flex": null,
            "_model_name": "LayoutModel",
            "justify_items": null,
            "grid_row": null,
            "max_height": null,
            "align_content": null,
            "visibility": null,
            "align_self": null,
            "height": null,
            "min_height": null,
            "padding": null,
            "grid_auto_rows": null,
            "grid_gap": null,
            "max_width": null,
            "order": null,
            "_view_module_version": "1.2.0",
            "grid_template_areas": null,
            "object_position": null,
            "object_fit": null,
            "grid_auto_columns": null,
            "margin": null,
            "display": null,
            "left": null
          }
        },
        "c24e1bccacf64da38c96f18783bfe5ea": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "HBoxModel",
          "state": {
            "_view_name": "HBoxView",
            "_dom_classes": [],
            "_model_name": "HBoxModel",
            "_view_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_view_count": null,
            "_view_module_version": "1.5.0",
            "box_style": "",
            "layout": "IPY_MODEL_eaa9995344a8439586bebfb2f11bb51a",
            "_model_module": "@jupyter-widgets/controls",
            "children": [
              "IPY_MODEL_3629ef84378e454baf09d7ec15aa09ef",
              "IPY_MODEL_60e55886a6ad40ceb504ea1cedcd1d97"
            ]
          }
        },
        "eaa9995344a8439586bebfb2f11bb51a": {
          "model_module": "@jupyter-widgets/base",
          "model_name": "LayoutModel",
          "state": {
            "_view_name": "LayoutView",
            "grid_template_rows": null,
            "right": null,
            "justify_content": null,
            "_view_module": "@jupyter-widgets/base",
            "overflow": null,
            "_model_module_version": "1.2.0",
            "_view_count": null,
            "flex_flow": null,
            "width": null,
            "min_width": null,
            "border": null,
            "align_items": null,
            "bottom": null,
            "_model_module": "@jupyter-widgets/base",
            "top": null,
            "grid_column": null,
            "overflow_y": null,
            "overflow_x": null,
            "grid_auto_flow": null,
            "grid_area": null,
            "grid_template_columns": null,
            "flex": null,
            "_model_name": "LayoutModel",
            "justify_items": null,
            "grid_row": null,
            "max_height": null,
            "align_content": null,
            "visibility": null,
            "align_self": null,
            "height": null,
            "min_height": null,
            "padding": null,
            "grid_auto_rows": null,
            "grid_gap": null,
            "max_width": null,
            "order": null,
            "_view_module_version": "1.2.0",
            "grid_template_areas": null,
            "object_position": null,
            "object_fit": null,
            "grid_auto_columns": null,
            "margin": null,
            "display": null,
            "left": null
          }
        },
        "3629ef84378e454baf09d7ec15aa09ef": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "FloatProgressModel",
          "state": {
            "_view_name": "ProgressView",
            "style": "IPY_MODEL_a0de905c157d4d149eb72607aa6ab724",
            "_dom_classes": [],
            "description": "",
            "_model_name": "FloatProgressModel",
            "bar_style": "success",
            "max": 1,
            "_view_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "value": 1,
            "_view_count": null,
            "_view_module_version": "1.5.0",
            "orientation": "horizontal",
            "min": 0,
            "description_tooltip": null,
            "_model_module": "@jupyter-widgets/controls",
            "layout": "IPY_MODEL_b707c3df62ba482e9c998b0812d32f17"
          }
        },
        "60e55886a6ad40ceb504ea1cedcd1d97": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "HTMLModel",
          "state": {
            "_view_name": "HTMLView",
            "style": "IPY_MODEL_a4ee658e4e0a4d199bcee9b5f6169133",
            "_dom_classes": [],
            "description": "",
            "_model_name": "HTMLModel",
            "placeholder": "​",
            "_view_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "value": " 8192/? [00:00&lt;00:00, 11043.18it/s]",
            "_view_count": null,
            "_view_module_version": "1.5.0",
            "description_tooltip": null,
            "_model_module": "@jupyter-widgets/controls",
            "layout": "IPY_MODEL_0a18f436171646028a62cee575a2547c"
          }
        },
        "a0de905c157d4d149eb72607aa6ab724": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "ProgressStyleModel",
          "state": {
            "_view_name": "StyleView",
            "_model_name": "ProgressStyleModel",
            "description_width": "initial",
            "_view_module": "@jupyter-widgets/base",
            "_model_module_version": "1.5.0",
            "_view_count": null,
            "_view_module_version": "1.2.0",
            "bar_color": null,
            "_model_module": "@jupyter-widgets/controls"
          }
        },
        "b707c3df62ba482e9c998b0812d32f17": {
          "model_module": "@jupyter-widgets/base",
          "model_name": "LayoutModel",
          "state": {
            "_view_name": "LayoutView",
            "grid_template_rows": null,
            "right": null,
            "justify_content": null,
            "_view_module": "@jupyter-widgets/base",
            "overflow": null,
            "_model_module_version": "1.2.0",
            "_view_count": null,
            "flex_flow": null,
            "width": null,
            "min_width": null,
            "border": null,
            "align_items": null,
            "bottom": null,
            "_model_module": "@jupyter-widgets/base",
            "top": null,
            "grid_column": null,
            "overflow_y": null,
            "overflow_x": null,
            "grid_auto_flow": null,
            "grid_area": null,
            "grid_template_columns": null,
            "flex": null,
            "_model_name": "LayoutModel",
            "justify_items": null,
            "grid_row": null,
            "max_height": null,
            "align_content": null,
            "visibility": null,
            "align_self": null,
            "height": null,
            "min_height": null,
            "padding": null,
            "grid_auto_rows": null,
            "grid_gap": null,
            "max_width": null,
            "order": null,
            "_view_module_version": "1.2.0",
            "grid_template_areas": null,
            "object_position": null,
            "object_fit": null,
            "grid_auto_columns": null,
            "margin": null,
            "display": null,
            "left": null
          }
        },
        "a4ee658e4e0a4d199bcee9b5f6169133": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "DescriptionStyleModel",
          "state": {
            "_view_name": "StyleView",
            "_model_name": "DescriptionStyleModel",
            "description_width": "",
            "_view_module": "@jupyter-widgets/base",
            "_model_module_version": "1.5.0",
            "_view_count": null,
            "_view_module_version": "1.2.0",
            "_model_module": "@jupyter-widgets/controls"
          }
        },
        "0a18f436171646028a62cee575a2547c": {
          "model_module": "@jupyter-widgets/base",
          "model_name": "LayoutModel",
          "state": {
            "_view_name": "LayoutView",
            "grid_template_rows": null,
            "right": null,
            "justify_content": null,
            "_view_module": "@jupyter-widgets/base",
            "overflow": null,
            "_model_module_version": "1.2.0",
            "_view_count": null,
            "flex_flow": null,
            "width": null,
            "min_width": null,
            "border": null,
            "align_items": null,
            "bottom": null,
            "_model_module": "@jupyter-widgets/base",
            "top": null,
            "grid_column": null,
            "overflow_y": null,
            "overflow_x": null,
            "grid_auto_flow": null,
            "grid_area": null,
            "grid_template_columns": null,
            "flex": null,
            "_model_name": "LayoutModel",
            "justify_items": null,
            "grid_row": null,
            "max_height": null,
            "align_content": null,
            "visibility": null,
            "align_self": null,
            "height": null,
            "min_height": null,
            "padding": null,
            "grid_auto_rows": null,
            "grid_gap": null,
            "max_width": null,
            "order": null,
            "_view_module_version": "1.2.0",
            "grid_template_areas": null,
            "object_position": null,
            "object_fit": null,
            "grid_auto_columns": null,
            "margin": null,
            "display": null,
            "left": null
          }
        }
      }
    }
  },
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "view-in-github",
        "colab_type": "text"
      },
      "source": [
        "<a href=\"https://colab.research.google.com/github/CIS-522/course-content/blob/main/tutorials/W05_Regularization/W5_Homework.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "ZhzzdfoH8O34"
      },
      "source": [
        "# CIS-522 Week 5 Homework\n",
        "\n",
        "\n",
        "**Instructor:** Lyle Ungar\n",
        "\n",
        "**Content Creators:** Jordan Lei\n"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "R_VqTwG09NEn",
        "cellView": "form"
      },
      "source": [
        "#@markdown What is your Pennkey and pod? (text, not numbers, e.g. bfranklin)\n",
        "my_pennkey = 'value' #@param {type:\"string\"}\n",
        "my_pod = 'astute-jellyfish' #@param ['Select', 'euclidean-wombat', 'sublime-newt', 'buoyant-unicorn', 'lackadaisical-manatee','indelible-stingray','superfluous-lyrebird','discreet-reindeer','quizzical-goldfish','ubiquitous-cheetah','nonchalant-crocodile','fashionable-lemur','spiffy-eagle','electric-emu','quotidian-lion','astute-jellyfish', 'quantum-herring']\n",
        "\n",
        "# start timing\n",
        "import time\n",
        "try:t0;\n",
        "except NameError: t0 = time.time()\n"
      ],
      "execution_count": 1,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "MPBNHacqXkrC",
        "cellView": "form",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "dd470e49-76e2-48cf-d267-9f72640fa4a5"
      },
      "source": [
        "#@markdown Run this cell for imports. It should print \"cuda\"\n",
        "#@markdown \n",
        "from __future__ import print_function\n",
        "import torch\n",
        "import pathlib\n",
        "import torch.nn as nn\n",
        "import torch.nn.functional as F\n",
        "import torch.optim as optim\n",
        "from torchvision import datasets, transforms\n",
        "from torchvision.datasets import ImageFolder\n",
        "from torch.utils.data import DataLoader, TensorDataset\n",
        "import time\n",
        "import numpy as np\n",
        "import matplotlib.pyplot as plt\n",
        "import copy\n",
        "\n",
        "torch.manual_seed(2021)\n",
        "device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n",
        "print(device)"
      ],
      "execution_count": 2,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "cuda\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "0qzHTBpz9hy4"
      },
      "source": [
        "# Part 1. Attack!\n",
        "In this homework, you will implement a simple adversarial attack on a neural network trained on MNIST handwritten digits. It might sound complicated, but we'll guide you through it step by step. First, let's download and familiarize ourselves with the dataset. \n",
        "\n",
        "**Run the cell below. Do not modify.**\n"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "EQAEcBpEXsAf",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 698,
          "referenced_widgets": [
            "9d491335bbca4d5c8a19cee359753550",
            "db3e065b5beb406280291a97df02ae19",
            "8b28a0eef01645f0a656ad12213942bd",
            "fba9a8c97e604df7a7f9db8cbac56f00",
            "2f7ac9f494674fbd89837fed0617d291",
            "75b1108264d746138c493220ad8477aa",
            "5bb338a1f35a46139174bd02e9b4b1f3",
            "e922415f57914427a8777c051081c094",
            "b0fb7494f9a6411c883e75ce3abed7a9",
            "7e945698d3484fef95f009521dd82987",
            "a7983575d08145839f029e607b83f154",
            "3775f41ba88f43a6ad52a4bee451c3b8",
            "f50db837dec542e0acdf4b1a66b493d4",
            "290985f35f2a47e5a209981ca3679bc5",
            "3badfe47858d43f68a2d497a4ac009fa",
            "88eac33ca8ef43eda70f90000c11124a",
            "e03e9765e6b5469299552f4c07762285",
            "f0591e73e0d94af78d4f3085764e8746",
            "2124c1492c744ed2ba519bd274f0c90f",
            "f9c8ea2bda7d430f88693c0eda8a1d4a",
            "3b4ad40f535049738154dbbcfa2966bf",
            "05429b65a91b49dab1ca4e3461d9de30",
            "d3cf3f3f647b4280a101c41539db3586",
            "5dd7edbcb0a64590a1252524b34ca67e",
            "c24e1bccacf64da38c96f18783bfe5ea",
            "eaa9995344a8439586bebfb2f11bb51a",
            "3629ef84378e454baf09d7ec15aa09ef",
            "60e55886a6ad40ceb504ea1cedcd1d97",
            "a0de905c157d4d149eb72607aa6ab724",
            "b707c3df62ba482e9c998b0812d32f17",
            "a4ee658e4e0a4d199bcee9b5f6169133",
            "0a18f436171646028a62cee575a2547c"
          ]
        },
        "outputId": "e3c578f6-c5c9-4994-d0a0-64eb625005be"
      },
      "source": [
        "dataset = datasets.MNIST(\"/content/\", download = True, train = True, transform = transforms.ToTensor())\n",
        "\n",
        "len_train = int(0.8 * len(dataset))\n",
        "len_val = len(dataset) - len_train\n",
        "train_dataset, val_dataset = torch.utils.data.random_split(dataset, [len_train, len_val])\n",
        "\n",
        "#train_loader is the data loader containing the training samples\n",
        "train_loader = DataLoader(train_dataset, batch_size = 64, shuffle = True)\n",
        "#val_loader is the data loader containing the validation samples\n",
        "val_loader = DataLoader(val_dataset, batch_size = 64, shuffle = True)\n",
        "\n",
        "#visualize one of the elements\n",
        "base_image = dataset[0][0].reshape(1, 784)\n",
        "plt.imshow(base_image.reshape(28, 28).numpy())\n",
        "plt.show()\n",
        "print(\"Above, I have an image with the corresponding label:\", dataset[0][1])"
      ],
      "execution_count": 3,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "Downloading http://yann.lecun.com/exdb/mnist/train-images-idx3-ubyte.gz to /content/MNIST/raw/train-images-idx3-ubyte.gz\n"
          ],
          "name": "stdout"
        },
        {
          "output_type": "display_data",
          "data": {
            "application/vnd.jupyter.widget-view+json": {
              "model_id": "9d491335bbca4d5c8a19cee359753550",
              "version_minor": 0,
              "version_major": 2
            },
            "text/plain": [
              "HBox(children=(FloatProgress(value=1.0, bar_style='info', max=1.0), HTML(value='')))"
            ]
          },
          "metadata": {
            "tags": []
          }
        },
        {
          "output_type": "stream",
          "text": [
            "Extracting /content/MNIST/raw/train-images-idx3-ubyte.gz to /content/MNIST/raw\n",
            "Downloading http://yann.lecun.com/exdb/mnist/train-labels-idx1-ubyte.gz to /content/MNIST/raw/train-labels-idx1-ubyte.gz\n"
          ],
          "name": "stdout"
        },
        {
          "output_type": "display_data",
          "data": {
            "application/vnd.jupyter.widget-view+json": {
              "model_id": "b0fb7494f9a6411c883e75ce3abed7a9",
              "version_minor": 0,
              "version_major": 2
            },
            "text/plain": [
              "HBox(children=(FloatProgress(value=1.0, bar_style='info', max=1.0), HTML(value='')))"
            ]
          },
          "metadata": {
            "tags": []
          }
        },
        {
          "output_type": "stream",
          "text": [
            "Extracting /content/MNIST/raw/train-labels-idx1-ubyte.gz to /content/MNIST/raw\n",
            "Downloading http://yann.lecun.com/exdb/mnist/t10k-images-idx3-ubyte.gz to /content/MNIST/raw/t10k-images-idx3-ubyte.gz\n"
          ],
          "name": "stdout"
        },
        {
          "output_type": "display_data",
          "data": {
            "application/vnd.jupyter.widget-view+json": {
              "model_id": "e03e9765e6b5469299552f4c07762285",
              "version_minor": 0,
              "version_major": 2
            },
            "text/plain": [
              "HBox(children=(FloatProgress(value=1.0, bar_style='info', max=1.0), HTML(value='')))"
            ]
          },
          "metadata": {
            "tags": []
          }
        },
        {
          "output_type": "stream",
          "text": [
            "Extracting /content/MNIST/raw/t10k-images-idx3-ubyte.gz to /content/MNIST/raw\n",
            "Downloading http://yann.lecun.com/exdb/mnist/t10k-labels-idx1-ubyte.gz to /content/MNIST/raw/t10k-labels-idx1-ubyte.gz\n"
          ],
          "name": "stdout"
        },
        {
          "output_type": "display_data",
          "data": {
            "application/vnd.jupyter.widget-view+json": {
              "model_id": "c24e1bccacf64da38c96f18783bfe5ea",
              "version_minor": 0,
              "version_major": 2
            },
            "text/plain": [
              "HBox(children=(FloatProgress(value=1.0, bar_style='info', max=1.0), HTML(value='')))"
            ]
          },
          "metadata": {
            "tags": []
          }
        },
        {
          "output_type": "stream",
          "text": [
            "Extracting /content/MNIST/raw/t10k-labels-idx1-ubyte.gz to /content/MNIST/raw\n",
            "Processing...\n",
            "Done!\n",
            "\n",
            "\n"
          ],
          "name": "stdout"
        },
        {
          "output_type": "stream",
          "text": [
            "/usr/local/lib/python3.6/dist-packages/torchvision/datasets/mnist.py:480: UserWarning: The given NumPy array is not writeable, and PyTorch does not support non-writeable tensors. This means you can write to the underlying (supposedly non-writeable) NumPy array using the tensor. You may want to copy the array to protect its data or make it writeable before converting it to a tensor. This type of warning will be suppressed for the rest of this program. (Triggered internally at  /pytorch/torch/csrc/utils/tensor_numpy.cpp:141.)\n",
            "  return torch.from_numpy(parsed.astype(m[2], copy=False)).view(*s)\n"
          ],
          "name": "stderr"
        },
        {
          "output_type": "stream",
          "text": [
            "\n",
            "\n"
          ],
          "name": "stdout"
        },
        {
          "output_type": "display_data",
          "data": {
            "image/png": "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\n",
            "text/plain": [
              "<Figure size 432x288 with 1 Axes>"
            ]
          },
          "metadata": {
            "tags": [],
            "needs_background": "light"
          }
        },
        {
          "output_type": "stream",
          "text": [
            "Above, I have an image with the corresponding label: 5\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "o6FxzcrN_gvi"
      },
      "source": [
        "## 1.1 Network\n",
        "MNIST digits come in images of size 28 x 28, and have an output of size 10. Let's construct a simple feedforward network with a *single hidden layer of size 64*. That is, our network should be shape *input --> 64 --> output*, with ReLU activations after each layer.\n",
        "\n",
        "**Your turn. Fill in the missing parts of the network definition**"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "9ujcd6N4cXNU"
      },
      "source": [
        "class Net1(nn.Module): \n",
        "  def __init__(self):\n",
        "    super(Net1, self).__init__()\n",
        "    self.l1 = ... #TODO: add the first linear module from input size to hidden size\n",
        "    self.l2 = ... #TODO: add the second linear module from hidden size to output size\n",
        "  def forward(self, x): \n",
        "    x = ... #TODO: pass x through the first linear module, then through relu\n",
        "    x = ... #TODO: pass x through the second linear module, then through relu\n",
        "    return x"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "8I07IF7uBoyn"
      },
      "source": [
        "## 1.2 Define Functions\n",
        "Now we want to define `train` and `test` functions to train and test our network, respectively. Fill in the \"TODO\" sections below for the train and test functions. \n",
        "\n",
        "**Your turn. Fill in the missing parts of the `train` and `test` functions**\n"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "9flZGP5jdtKX"
      },
      "source": [
        "def train(train_loader, net, optimizer, criterion, epochs = 10):\n",
        "  for epoch in range(epochs): \n",
        "    c = 0\n",
        "    total_loss = 0\n",
        "    total_correct = 0\n",
        "    for i, (image, label) in enumerate(train_loader):\n",
        "      #As a safety precaution, we zero out the gradients in the beginning\n",
        "      optimizer.zero_grad()\n",
        "\n",
        "\n",
        "      #MNIST images are [batch_size, 1, 28, 28] by default, so we need to\n",
        "      #reshape them to [batch_size, 784] for our network. We also need\n",
        "      #to send our images and labels to our GPU\n",
        "      image = image.view(-1, 784).to(device)\n",
        "      label = label.to(device)\n",
        "\n",
        "      #use your network to make a prediction\n",
        "      prediction = ... #TODO: define prediction\n",
        "\n",
        "      #calculate the loss using the criterion, prediction, and label\n",
        "      loss = ... #TODO: calculate the loss\n",
        "      \n",
        "      #make the backward pass on your loss\n",
        "      ... #TODO: backward pass\n",
        "\n",
        "      #make a step with your optimizer\n",
        "      ... #TODO step with your optimizer\n",
        "\n",
        "      \n",
        "      predicted_class = torch.argmax(prediction, 1)\n",
        "      correct = torch.sum((predicted_class == label))\n",
        "\n",
        "      total_loss += loss\n",
        "      total_correct += correct\n",
        "      c += len(label)\n",
        "\n",
        "      if i%500 == 0:\n",
        "        print(\"[Epoch %s]\\tAcc:%.4f\\tLoss:%.4f\"%(epoch, (total_correct/c).item(), (total_loss/c).item()))\n",
        "\n",
        "\n",
        "def test(test_loader, net, criterion): \n",
        "  c = 0\n",
        "  total_loss = 0\n",
        "  total_correct = 0\n",
        "  for i, (image, label) in enumerate(test_loader): \n",
        "    image = image.view(-1, 784).to(device)\n",
        "    label = label.to(device)\n",
        "    #use your network to make a prediction\n",
        "    prediction = ... #TODO: define prediction (feel free to copy+paste from above)\n",
        "\n",
        "    #calculate the loss using the criterion, prediction, and label\n",
        "    loss = ... #TODO define loss (feel free to copy+paste from above)\n",
        "\n",
        "    predicted_class = torch.argmax(prediction, 1)\n",
        "    total_loss += loss.item()\n",
        "    total_correct += torch.sum((predicted_class == label)).item()\n",
        "    c += len(label)\n",
        "\n",
        "  return total_loss/c, total_correct/c"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "xnSgXRsZC2tE"
      },
      "source": [
        "## 1.3 Train the Network\n",
        "Now let's train the network. Define the following: \n",
        "* `net`: initialize the network with the `Net1` class. Make sure you send the network to cuda!\n",
        "* `optimizer`: use an Adam optimizer with learning rate 0.01, and initialize it with your network parameters.\n",
        "* `criterion`: choose a good criterion for this task. Consider looking at: https://pytorch.org/docs/stable/nn.html#loss-function. \n",
        "\n",
        "**Your turn. Define the net, optimizer, and criterion.**"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "H-NzkD3reJBU"
      },
      "source": [
        "net = ... #TODO: define net, send it to device\n",
        "optimizer = ... #TODO: define optimizer\n",
        "criterion = ... #TODO: choose a good criterion\n",
        "\n",
        "train(train_loader, net, optimizer, criterion)\n",
        "loss, accuracy = test(val_loader, net, criterion)\n",
        "print(\"Evaluation\\n\\tTest Loss: %.4f\\tTest Accuracy: %.2f%%\"%(loss, accuracy*100))"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Mvd1KRvsD0kR"
      },
      "source": [
        "## 1.4 How Did We Do? \n",
        "Confirm that your test loss above is exactly `0.0027` and your Test Accuracy is exactly `96.53%`. Don't move on until you confirm this is the case; if you get stuck, feel free to phone a friend or your friendly neighborhood pod leader.\n",
        "\n",
        "Now let's see how our network performs on the image we showed above! Run the cell below. \n",
        "**Run the cell below. Do not modify**"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "hPdKnz0jqwv3"
      },
      "source": [
        "base_image = dataset[0][0].reshape(1, 784)\n",
        "plt.imshow(base_image.reshape(28, 28).numpy())\n",
        "plt.show()\n",
        "net_prediction = torch.argmax(net(base_image.to(device))).item()\n",
        "print(\"My Network Predicts That This Number Is... %s\"%(net_prediction))"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Pgl5l7zgEniR"
      },
      "source": [
        "## 1.5 Adversarial Attack\n",
        "Now for the fun part. Let's attack our network by creating an image that looks almost exactly like the one above, but makes it mistake the digit for a 3! How do we do that? \n",
        "\n",
        "Here's one way of doing it: instead of updating the **weights of our network**, what if we updated the **pixels of our image** using gradient descent? Take a moment to read that again. We're going to require gradients on our **image**, and then update it until the network is properly fooled!\n",
        "\n",
        "Our problem is complex though. We have two goals: \n",
        "\n",
        "\n",
        "1.   `criterion_1`: We want to fool the network into thinking that the image is a 3, not a 5. \n",
        "2.   `criterion_2`: We want to make sure the modified image `mod_image` looks as much like the original `base_image` as possible.\n",
        "\n",
        "Our loss will be a weighted sum between the losses evaluated on these two criteria, i.e. `loss = weight_1 * loss_1 + weight_2 * loss_2`. For our code below, let `weight_1 = 0.001` and `weight_2 = 1`.\n",
        "\n",
        "**Your turn. Define `criterion_1`, `criterion_2`, `loss_1`, `loss_2`, and `loss`. Run the code; if your attack is successful it will print \"ATTACK SUCCESSFUL\"**\n",
        "\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "TfMq1XOmrWja"
      },
      "source": [
        "#create a copy of base_image which we can modify\n",
        "mod_image = base_image.clone() \n",
        "#our target class is 3. We send this to the device\n",
        "target = torch.LongTensor([3]).to(device)\n",
        "optimizer = optim.SGD([mod_image.requires_grad_(True)], lr = 0.01)\n",
        "\n",
        "#Choose a good criterion to compare our prediction with the target\n",
        "#hint: these are categorical variables\n",
        "criterion1 = ... #TODO: choose criterion1\n",
        "\n",
        "#Choose a good criterion which describes how \"far off\" our mod_image\n",
        "#differs from base_image\n",
        "#hint: think about how we might measure the \"distance\" between two images\n",
        "criterion2 = ... #TODO: choose criterion2\n",
        "\n",
        "\n",
        "for i in range(10000):\n",
        "  prediction = net(mod_image.to(device))\n",
        "\n",
        "  #loss_1 is the result of evaluating criterion_1 on the prediction of the net\n",
        "  #compared to the target class.\n",
        "  loss_1 = ... #TODO: define loss_1\n",
        "\n",
        "  #loss_2 is the result of evaluating criterion_2 on the current image\n",
        "  #(mod_image) compared to the original image (base_image).\n",
        "  loss_2 = ... #TODO: define loss_2\n",
        "\n",
        "  #the final loss is a weighted sum of the losses, where weight_1 = 0.001 and weight_2 = 1\n",
        "  loss = ... #TODO: define loss\n",
        "  loss.backward()\n",
        "  optimizer.step()\n",
        "\n",
        "  predicted_class = torch.argmax(prediction)\n",
        "\n",
        "  if predicted_class == target:\n",
        "    print(\"Predicted Class: %s, Loss: %s, ATTACK SUCCESSFUL!\"%(predicted_class.item(), loss.item()))\n",
        "    break\n",
        "  else:\n",
        "    if i%10 == 0: \n",
        "      print(\"Predicted Class: %s, Loss: %s\"%(predicted_class.item(), loss.item()))"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "RXk8bNKbSK6A"
      },
      "source": [
        "So what does our image look like now? Run the cell below to compare the original input to the modified image, and how our network classifies each. Did we succeed?\n",
        "\n",
        "**Take a screenshot of the output of this cell and save it for later.**"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "cellView": "form",
        "id": "-K_6lmVTub3z"
      },
      "source": [
        "#@markdown Run this cell to display your adversarial attack!\n",
        "net.eval()\n",
        "plt.imshow(base_image.reshape(28, 28).detach().numpy())\n",
        "plt.show()\n",
        "net_prediction = torch.argmax(net(base_image.to(device))).item()\n",
        "print(\"My Network Predicts That This Number Is... %s\"%(net_prediction))\n",
        "plt.imshow(mod_image.reshape(28, 28).detach().numpy())\n",
        "plt.show()\n",
        "net_prediction = torch.argmax(net(mod_image.to(device))).item()\n",
        "print(\"My Network Predicts That This Number Is... %s\"%(net_prediction))"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "TVjcgCYTS0Oc"
      },
      "source": [
        "# Part 2. Defend!\n",
        "In this next part of the homework, we will ask you to use **regularization** to defend against the adversarial image you constructed in part 1. Try each of the following regularization techniques: \n",
        "* Early stopping\n",
        "* Dropout (https://pytorch.org/docs/stable/generated/torch.nn.Dropout.html)\n",
        "* L2 regularization (hint: see the `weight_decay` parameter in optim.Adam: https://pytorch.org/docs/stable/optim.html)\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "DBsKM_pJe1gN"
      },
      "source": [
        "## 2.1 Train your Defense\n",
        "In this section, you'll train a network which will be able to detect that the adversarial image is a 5, not a 3. Feel free to copy + paste code from the above sections as needed. \n",
        "**Make sure your network is exactly the same architecture as you had (with the exception of adding dropout layers)!**\n",
        "\n",
        "**Your turn. Train your network on each regularization technique below. We recommend that you try each technique individually, and then combine them if necessary. Once your net completes training, you may test it on the adversarial image in the following section.**"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "RLtb_EYauifN"
      },
      "source": [
        "#Net2 should be the same architecture as Net1 with the exception of dropout layers\n",
        "class Net2(nn.Module): \n",
        "  ... #TODO: create class Net2"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "CUlHTpWKTDA8"
      },
      "source": [
        "net = ... #TODO: define net\n",
        "optimizer = ... #TODO: define optimizer\n",
        "criterion = ... #TODO: choose a good criterion\n",
        "\n",
        "train(train_loader, net, optimizer, criterion)\n",
        "loss, accuracy = test(val_loader, net, criterion)\n",
        "print(\"Evaluation\\n\\tTest Loss: %.4f\\tTest Accuracy: %.2f%%\"%(loss, accuracy*100))"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "IarN6lE2dvcC"
      },
      "source": [
        "## 2.2 How Did We Do?\n",
        "Run the code below to test if your regularization worked. If successful, it will print \"DEFENSE SUCCESSFUL\". \n",
        "\n",
        "**Run the code below. Do not modify. If successful, take a screenshot and write down what regularization parameters led to your success**"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "cellView": "form",
        "id": "MMtdWWryTbB-"
      },
      "source": [
        "#@markdown Run this cell to test your defense!\n",
        "net.eval()\n",
        "\n",
        "plt.imshow(base_image.reshape(28, 28).detach().numpy())\n",
        "plt.show()\n",
        "prediction_orig = net(mod_image.to(device))\n",
        "net_predicted_class_orig = torch.argmax(prediction_orig).item()\n",
        "print(\"My Regularized Network Predicts That This Number Is... %s\"%(net_predicted_class_orig))\n",
        "plt.imshow(mod_image.reshape(28, 28).detach().numpy())\n",
        "plt.show()\n",
        "\n",
        "prediction = net(mod_image.to(device))\n",
        "net_predicted_class = torch.argmax(prediction).item()\n",
        "print(\"My Regularized Network Predicts That This Number Is... %s\"%(net_predicted_class))\n",
        "if net_predicted_class_orig == 5 and net_predicted_class == 5: \n",
        "  print(\"DEFENSE SUCCESSFUL!\")\n",
        "  saved_prediction = prediction\n",
        "else: \n",
        "  print(\"AW, SNAP! FOOLED AGAIN! GO BACK AND TRY A DIFFERENT REGULARIZATION COMBO\")"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "_e1Vj4cufg93"
      },
      "source": [
        "**Write answers to the following questions below**\n",
        "1. How did your regularized models compare to your original model, in terms of overall accuracy? How did they compare to one another?\n",
        "2. Did your regularized models successfully defend against the adversarial task? If so, what parameters contributed to your success? \n",
        "3. You might have noticed that your adversarial image successfully fooled your network under a lot of different regularization conditions. You can verify this yourself, but it turns out that this adversarial image is capable of fooling networks with different architectures, and even possibly other learning models (decision trees, K-means, etc.) trained on MNIST. *In short, attacking one network can create an effective attack on a wide variety of learning algorithms.* Given this information, describe what implications this has for machine learning for security, and why it is hard to defend against these attacks."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "CwEIFfWFeoFP"
      },
      "source": [
        "#Remove starter text and write your answer.\n",
        "q_2_2 = '''\n",
        "Your Answer Here\n",
        "1. Answer to Part 1\n",
        "2. Answer to Part 2\n",
        "3. Answer to Part 3\n",
        "'''"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "d1KoSvRJHvor"
      },
      "source": [
        "# Part 3. Deep Learning, Deeper Thinking\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "29bQF6U__uxX"
      },
      "source": [
        "Now that you've gotten familiar with adversarial attacks and regularization, it's time to think about some of the implications of these attacks. First, read the following:\r\n",
        "\r\n",
        "* https://openai.com/blog/adversarial-example-research/\r\n",
        "* https://www.sciencedirect.com/science/article/pii/S0743731518309183\r\n",
        "(accessible through Penn Libraries)\r\n",
        "\r\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "RA9V9UtVQF2C"
      },
      "source": [
        "## Part 3.1 Reflect\n",
        "**Short answer: what type of adversarial attack did we conduct in section 1.5 (choose the most similar one based on the descriptions in the second paper)?**\n"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "hQPHV_3UQVjd"
      },
      "source": [
        "q_3_1 = '''\n",
        "Your Answer to 3.1 Here\n",
        "'''"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Z_u3T9h6QAMo"
      },
      "source": [
        "## Part 3.1 Discuss\n",
        "**In 200-300 words, please answer the following questions, and also post these to Slack**\n",
        "* As engineers, how can we safeguard against adversarial attacks? Give a real-world example of what an adversarial attack might look like (aside from the one you just deployed), and what consequences it might have.\n",
        "* How might adversarial attacks on machine learning algorithms impact public trust of these algorithms? How might we communicate these risks to the public? \n",
        "* In your own words, why doesn't \"gradient masking\" work?\n"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "HqkX0d-eP1tx"
      },
      "source": [
        "q_3_2 = '''\n",
        "Your Answer to 3.2 Here (200-300 Words)\n",
        "'''"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "u7wWXWiLBhrD"
      },
      "source": [
        "# Part 4. Rethinking Generalization\r\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "uLAtJonqBrb0"
      },
      "source": [
        "Read the first three pages of this article on \"Understanding Deep Learning Requires Rethinking Generalization\" [https://arxiv.org/pdf/1611.03530.pdf] and Answer the following questions:"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "vt2nFHMfCzWu"
      },
      "source": [
        "1. Why is it important that neural nets can learn to get zero training error on \r\n",
        "images with randomized labels, or even with images that are pure random noise?"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "wqagv9ofClzt"
      },
      "source": [
        "q_4_1 = \"\"\"\r\n",
        "Your Answer\r\n",
        "\"\"\""
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "MrARQcJrDHXy"
      },
      "source": [
        "2. How many weights are needed in a 2-layer ReLU to fit n observations each of dimension d?\r\n"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "vovWW2c-DYDv"
      },
      "source": [
        "q_4_2 = \"\"\"\r\n",
        "Your Answer\r\n",
        "\"\"\""
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "jrdJkZ-zDc-3"
      },
      "source": [
        "3. Are standard regularization methods (e.g. L1, L2, early stopping) required to prevent overfitting?"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "pj8CI_26Dk1T"
      },
      "source": [
        "q_4_3 = \"\"\"\r\n",
        "Your Answer\r\n",
        "\"\"\""
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "SH8mN2tyDsM7"
      },
      "source": [
        "4. The authors argue that “implicit regularization” is more important than explicit regularization. What do they mean by “implicit regularization” and how does it work?"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "YhQ4RUpfDthi"
      },
      "source": [
        "q_4_4 = \"\"\"\r\n",
        "Your Answer\r\n",
        "\"\"\""
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "jU_EUAJyQnBm"
      },
      "source": [
        "# Part 5. Better-Know-A-Pod\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "4WGPXvcdXpbX"
      },
      "source": [
        "*This section is designed to let you better know your pod mates. You are encouraged to discuss these with your pod mates during pod sessions or during pod social events, but NOT over Slack. The idea is to get to know your pod mates face-to-face.*\n",
        "\n",
        "**List 2 other members of your pod - not the same two that you listed last homework. What are they most excited about doing after the pandemic is over, and why? (around 100 words each).**\n",
        "\n",
        "\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "nEjrRXJ6Yjwy"
      },
      "source": [
        "better_know_a_pod = '''\n",
        "Your Answer to Better-Know-A-Pod Here (100 words each)\n",
        "'''"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "JzdZmL_7gtjq"
      },
      "source": [
        "# Submission\n",
        "**Load the airtable below. Remember to attach the screenshots you took from section 1.5 and section 2.2!**"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "bRwrR_5VesBi",
        "cellView": "form"
      },
      "source": [
        "#@markdown #Run Cell to Show Airtable Form\n",
        "#@markdown ##**Confirm your answers and then click \"Submit\"**\n",
        "import time\n",
        "import numpy as np\n",
        "import urllib.parse\n",
        "from IPython.display import IFrame\n",
        "def prefill_form(src, fields: dict):\n",
        "  '''\n",
        "  src: the original src url to embed the form\n",
        "  fields: a dictionary of field:value pairs,\n",
        "  e.g. {\"pennkey\": my_pennkey, \"location\": my_location}\n",
        "  '''\n",
        "  prefill_fields = {}\n",
        "  for key in fields:\n",
        "      new_key = 'prefill_' + key\n",
        "      prefill_fields[new_key] = fields[key]\n",
        "  prefills = urllib.parse.urlencode(prefill_fields)\n",
        "  src = src + prefills\n",
        "  return src\n",
        "\n",
        "#autofill fields if they are not present\n",
        "#a missing pennkey and pod will result in an Airtable warning\n",
        "#which is easily fixed user-side.\n",
        "try: my_pennkey;\n",
        "except NameError: my_pennkey = \"\"\n",
        "try: my_pod;\n",
        "except NameError: my_pod = \"Select\"\n",
        "try: q_2_2;\n",
        "except NameError: q_2_2 = \"\"\n",
        "try: q_3_1;\n",
        "except NameError: q_3_1 = \"\"\n",
        "try: q_3_2;\n",
        "except NameError: q_3_2 = \"\"\n",
        "try: q_4_1;\n",
        "except NameError: q_4_1 = \"\"\n",
        "try: q_4_2;\n",
        "except NameError: q_4_2 = \"\"\n",
        "try: q_4_3;\n",
        "except NameError: q_4_3 = \"\"\n",
        "try: q_4_4;\n",
        "except NameError: q_4_4 = \"\"\n",
        "\n",
        "#autofill time if it is not present\n",
        "try: t0;\n",
        "except NameError: t0 = time.time()\n",
        "try: t1;\n",
        "except NameError: t1 = time.time()\n",
        "times = np.array([t1])-t0\n",
        "\n",
        "fields = {\"pennkey\": my_pennkey,\n",
        "          \"pod\": my_pod,\n",
        "          \"q_2_2\":q_2_2,\n",
        "          \"q_3_1\":q_3_1,\n",
        "          \"q_3_2\":q_3_2,\n",
        "          \"q_4_1\":q_4_1,\n",
        "          \"q_4_2\":q_4_2,\n",
        "          \"q_4_3\":q_4_3,\n",
        "          \"q_4_4\":q_4_4,\n",
        "          \"better_know_a_pod\":better_know_a_pod,\n",
        "          \"cumulative_times\": times}\n",
        "\n",
        "src = \"https://airtable.com/embed/shrgO2VsoOSFLqCNz?\"\n",
        "\n",
        "#now instead of the original source url, we do: src = prefill_form(src, fields)\n",
        "display(IFrame(src = prefill_form(src, fields), width = 800, height = 400))"
      ],
      "execution_count": null,
      "outputs": []
    }
  ]
}